package com.practice.bootdemo.common;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;
import java.io.IOException;
import java.security.Key;
import java.util.Date;

/**
 * author :v-zhousq04
 * description: token工具类
 * create date: 2018/6/5 14:38
 * last modify by:v-zhousq04
 */
@Component
//@PropertySource(value = {"classpath:application-dev.properties"},encoding="utf-8")
public class JWTUtil {


    private static  String secret;

    @Value("${taoken.secret}")
    public void setSecret(String secret) {
        this.secret = secret;
    }

    public static String generateToken( String issuer, String subject, long ttlMillis) {

        //The JWT signature algorithm we will be using to sign the token
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;

        long nowMillis = System.currentTimeMillis();
        Date now = new Date(nowMillis);

        //We will sign our JWT with our ApiKey secret
        byte[] apiKeySecretBytes = DatatypeConverter.parseBase64Binary(secret);
        Key signingKey = new SecretKeySpec(apiKeySecretBytes, signatureAlgorithm.getJcaName());

        //Let's set the JWT Claims
        JwtBuilder builder = Jwts.builder()
                .setIssuedAt(now)
                .setSubject(subject)
                .setIssuer(issuer)
                .claim("userName","OOO1")
                .signWith(signatureAlgorithm, signingKey);

        //if it has been specified, let's add the expiration
        if (ttlMillis >= 0) {
            long expMillis = nowMillis + ttlMillis;
            Date exp = new Date(expMillis);
            builder.setExpiration(exp);
        }

        //Builds the JWT and serializes it to a compact, URL-safe string
        return builder.compact();
    }


    public static void parseToken(String jwt) {

        //This line will throw an exception if it is not a signed JWS (as expected)
        Claims claims = Jwts.parser()
                .setSigningKey(DatatypeConverter.parseBase64Binary(secret))
                .parseClaimsJws(jwt).getBody();
        System.out.println("Subject: " + claims.getSubject());
        System.out.println("Issuer: " + claims.getIssuer());
        System.out.println("Expiration: " + claims.getExpiration());
        System.out.println("userName: " + claims.get("userName"));
    }

    /**
     * base64加密
     * @param string
     * @return
     */
    public static String encode(String string){
        BASE64Encoder base64Encoder=new BASE64Encoder();
        return  base64Encoder.encode(string.getBytes());
    }

    /**
     * @author :v-zhousq04
     * @description: base64解码
     * @param :method params
     * @param keyString
     * @create date: 2017/12/18 16:37
     * @last modify by:v-zhousq04
     */
    public static String decode(String keyString){
        BASE64Decoder base64Decoder=new BASE64Decoder();
        try {
            String string=new String(base64Decoder.decodeBuffer(keyString));
            return string;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    /*public static void main(String[] args) {
       String s= generateToken("tom","tester",new Long(30*60*1000));
        System.out.println(s);
        parseToken(s);
    }*/
}
